<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">

    <title>Switch+Cameras using RTCMultiConnection</title>

    <meta name="description" content="Switch/Change Cameras in a live conference using RTCMultiConnection" />
    <meta name="keywords" content="WebRTC,RTCMultiConnection,Demos,Experiments,Samples,Examples" />

    <style>
        video {
            width: 100%;
        }
        button,
        input,
        select {
            font-weight: normal;
            padding: 2px 4px;
            text-decoration: none;
            display: inline-block;
            text-shadow: none;
            font-size: 16px;
            outline: none;
        }

        .make-center {
            text-align: center;
            padding: 5px 10px;
        }

        .video-parent-container {
            display: inline-block;
            border: 2px solid black;
            margin: 2px 5px;
            border-radius: 5px;
            object-fit: fill;
            width: 42%;
            background: black;
        }
    </style>
</head>

<body>
    <article>

        <header style="text-align: center;">
            <h1>Switch+Cameras using RTCMultiConnection</h1>
            <p>
                <a href="https://rtcmulticonnection.herokuapp.com/">HOME</a>
                <span> &copy; </span>
                <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a> .
                <a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a> .
                <a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a> .
                <a href="https://github.com/muaz-khan/RTCMultiConnection/issues?state=open" target="_blank">Latest issues</a> .
                <a href="https://github.com/muaz-khan/RTCMultiConnection/commits/master" target="_blank">What's New?</a>
            </p>
        </header>


        <div class="github-stargazers"></div>

        <section class="experiment">
            <div class="make-center">
                <input type="text" id="room-id" value="abcdef">
                <button id="open-room">Open Room</button>
                <button id="join-room">Join Room</button>
                <button id="open-or-join-room">Auto Open Or Join Room</button>

                <div id="room-urls" style="text-align: center;display: none;background: #F1EDED;margin: 15px -10px;border: 1px solid rgb(189, 189, 189);border-left: 0;border-right: 0;"></div>

                <br><br>
                <label for="audio-devices">Audio Devices:</label>
                <select id="audio-devices" disabled></select>
                <br>
                <label for="video-devices">Video Devices:</label>
                <select id="video-devices" disabled></select>
                <br>
                <button id="switch-camera" disabled>Switch Webcam</button>
                <button id="switch-microphone" disabled>Switch Microphone</button>
            </div>

            <div id="videos-container"></div>
        </section>

        <script src="/dist/RTCMultiConnection.min.js"></script>
        <script src="/socket.io/socket.io.js"></script>

        <script>
            // ......................................................
            // .......................UI Code........................
            // ......................................................

            document.getElementById('open-room').onclick = function() {
                disableInputButtons();
                connection.open(document.getElementById('room-id').value, function() {
                    showRoomURL(connection.sessionid);
                });
            };

            document.getElementById('join-room').onclick = function() {
                disableInputButtons();
                connection.join(document.getElementById('room-id').value);
            };

            document.getElementById('open-or-join-room').onclick = function() {
                disableInputButtons();
                connection.openOrJoin(document.getElementById('room-id').value, function(isRoomExists, roomid) {
                    if(!isRoomExists) {
                        showRoomURL(roomid);
                    }
                });
            };

            var chatContainer = document.querySelector('.chat-output');

            function appendDIV(event) {
                var div = document.createElement('div');
                div.innerHTML = event.data || event;
                chatContainer.insertBefore(div, chatContainer.firstChild);
                div.tabIndex = 0;
                div.focus();

                document.getElementById('input-text-chat').focus();
            }

            // ......................................................
            // ..................RTCMultiConnection Code.............
            // ......................................................

            var connection = new RTCMultiConnection();

            // by default, socket.io server is assumed to be deployed on your own URL
            connection.socketURL = '/';

            // comment-out below line if you do not have your own socket.io server
            // connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';

            connection.socketMessageEvent = 'switch-cameras-demo';

            connection.socketCustomEvent = connection.channel;

            connection.session = {
                audio: true,
                video: true
            };

            connection.sdpConstraints.mandatory = {
                OfferToReceiveAudio: true,
                OfferToReceiveVideo: true
            };

            function receiveCustomMessages() {
                connection.connectSocket(function(socket) {
                    socket.on(connection.socketCustomEvent, function(message) {
                        if(message.remoteUserId !== connection.userid) return;

                        if(!message.reloadVideo) return;

                        var streamEvent = connection.streamEvents[message.streamid];
                        if(!streamEvent) return;

                        var videoParentNode = document.getElementById(message.userid);
                        if(!videoParentNode) return;

                        setTimeout(function() {
                            videoParentNode.querySelector('video').src = URL.createObjectURL(streamEvent.stream);
                            videoParentNode.querySelector('video').play();
                        }, 2000);
                    });
                });
            }

            var videosContainer = document.getElementById('videos-container');
            connection.onstream = function(event) {
                event.mediaElement.id = '';

                if(event.mediaElement) {
                    event.mediaElement.muted = true;
                    delete event.mediaElement;
                }

                if(event.stream.mediaElement) {
                    event.stream.mediaElement.muted = true;
                    delete event.stream.mediaElement;
                }

                var videoParentNode = document.getElementById(event.userid);
                if(videoParentNode && event.type == 'local') {
                    var oldStream;
                    connection.attachStreams.forEach(function(stream) {
                        if(stream.streamid !== event.stream.streamid) {
                            oldStream = stream;
                        }
                    });

                    if(!oldStream) {
                        oldStream = connection.attachStreams[0];

                        if(!oldStream) return;
                    }

                    if(event.stream.getAudioTracks().length) {
                        oldStream.addTrack(event.stream.getAudioTracks()[0]);
                    }

                    if(event.stream.getVideoTracks().length) {
                        oldStream.addTrack(event.stream.getVideoTracks()[0]);
                    }

                    connection.attachStreams = [oldStream];

                    videoParentNode.querySelector('video').src = URL.createObjectURL(oldStream);
                    videoParentNode.querySelector('video').play();

                    connection.renegotiate();
                    connection.connectSocket(function(socket) {
                        connection.getAllParticipants().forEach(function(participantId) {
                            socket.emit(connection.socketCustomEvent, {
                                remoteUserId: participantId,
                                reloadVideo: true,
                                userid: connection.userid,
                                streamid: oldStream.streamid
                            });
                        });
                    });
                    return;
                }

                videoParentNode = document.createElement('div');
                videoParentNode.id = event.userid;
                videoParentNode.className = 'video-parent-container';

                var video = document.createElement('video');
                video.src = URL.createObjectURL(event.stream);

                video.controls = true;
                videoParentNode.appendChild(video);
                video.play();

                videosContainer.appendChild(videoParentNode);

                setTimeout(function() {
                    video.play(); // android
                }, 3000);

                if(event.type === 'remote' && !connection.alreadyHandlingRemoteMessages) {
                    connection.alreadyHandlingRemoteMessages = true;
                    receiveCustomMessages();

                    document.getElementById('switch-camera').disabled = false;
                    document.getElementById('switch-microphone').disabled = false;

                    videoDevices.disabled = false;
                    audioDevices.disabled = false;

                    videoDevices.onchange();
                    audioDevices.onchange();
                }
            };

            connection.onSettingLocalDescription = function(event) {
                var tries = 0;
                (function looper() {
                    if(tries > 10) return; // try till 10 seconds
                    tries++;

                    connection.getAllParticipants().forEach(function(p) {
                        var div = document.getElementById(p);
                        if(!div) return;

                        var video = div.querySelector('video');
                        if(!video || !!video.currentTime) return;

                        video.src = URL.createObjectURL(connection.peers[p].peer.getRemoteStreams()[0]);
                        video.play();
                    });

                    setTimeout(looper, 1000);
                })();
            };

            connection.onstreamended = function(event) {
                var div = document.getElementById(event.userid);
                if(div && div.parentNode) {
                    div.parentNode.removeChild(div);
                }
            };

            var videoDevices = document.getElementById('video-devices');
            var audioDevices = document.getElementById('audio-devices');

            videoDevices.onchange = function() {
                videoDevices.innerHTML = '';
                videoDevices.onchange = function() {};
                DetectRTC.load(function() {
                    DetectRTC.videoInputDevices.forEach(function(device) {
                        if(document.getElementById(device.id + device.label + device.kind)) {
                            return;
                        }

                        if(device.kind.indexOf('video') !== -1) {
                            var option = document.createElement('option');
                            option.id = device.id + device.label + device.kind;
                            option.innerHTML = device.label || device.id;
                            option.value = device.id;
                            videoDevices.appendChild(option);

                            if(connection.mediaConstraints.video.optional.length && connection.mediaConstraints.video.optional[0].sourceId === device.id) {
                                option.selected = true;
                            }
                        }
                    });
                });
            };

            audioDevices.onchange = function() {
                audioDevices.innerHTML = '';
                audioDevices.onchange = function() {};
                DetectRTC.load(function() {
                    DetectRTC.audioInputDevices.forEach(function(device) {
                        if(document.getElementById(device.id + device.label + device.kind)) {
                            return;
                        }

                        if(device.kind === 'audioinput') {
                            var option = document.createElement('option');
                            option.id = device.id + device.label + device.kind;
                            option.innerHTML = device.label || device.id;
                            option.value = device.id;
                            audioDevices.appendChild(option);

                            if(connection.mediaConstraints.audio.optional.length && connection.mediaConstraints.audio.optional[0].sourceId === device.id) {
                                option.selected = true;
                            }
                        }
                    });
                });
            };

            document.getElementById('switch-camera').onclick = function() {
                var videoSourceId = videoDevices.value;

                if(connection.mediaConstraints.video.optional.length && connection.attachStreams.length) {
                    if(connection.mediaConstraints.video.optional[0].sourceId === videoSourceId) {
                        alert('Selected video device is already selected.');
                        return;
                    }
                }

                connection.attachStreams.forEach(function(stream) {
                    stream.getVideoTracks().forEach(function(track) {
                        stream.removeTrack(track);

                        if(track.stop) {
                            track.stop();
                        }
                    });
                });

                connection.mediaConstraints.video.optional = [{
                    sourceId: videoSourceId
                }];

                connection.captureUserMedia();
            };

            document.getElementById('switch-microphone').onclick = function() {
                var audioSourceId = audioDevices.value;

                if(connection.mediaConstraints.audio.optional.length && connection.attachStreams.length) {
                    if(connection.mediaConstraints.audio.optional[0].sourceId === audioSourceId) {
                        alert('Selected audio device is already selected.');
                        return;
                    }
                }

                connection.attachStreams.forEach(function(stream) {
                    stream.getAudioTracks().forEach(function(track) {
                        stream.removeTrack(track);

                        if(track.stop) {
                            track.stop();
                        }
                    });
                });

                connection.mediaConstraints.audio.optional = [{
                    sourceId: videoSourceId
                }];

                connection.captureUserMedia();
            };

            function disableInputButtons() {
                document.getElementById('open-or-join-room').disabled = true;
                document.getElementById('open-room').disabled = true;
                document.getElementById('join-room').disabled = true;
                document.getElementById('room-id').disabled = true;
            }

            // ......................................................
            // ......................Handling Room-ID................
            // ......................................................

            function showRoomURL(roomid) {
                var roomHashURL = '#' + roomid;
                var roomQueryStringURL = '?roomid=' + roomid;

                var html = '<h2>Unique URL for your room:</h2><br>';

                html += 'Hash URL: <a href="' + roomHashURL + '" target="_blank">' + roomHashURL + '</a>';
                html += '<br>';
                html += 'QueryString URL: <a href="' + roomQueryStringURL + '" target="_blank">' + roomQueryStringURL + '</a>';

                var roomURLsDiv = document.getElementById('room-urls');
                roomURLsDiv.innerHTML = html;

                roomURLsDiv.style.display = 'block';
            }

            (function() {
                var params = {},
                    r = /([^&=]+)=?([^&]*)/g;

                function d(s) {
                    return decodeURIComponent(s.replace(/\+/g, ' '));
                }
                var match, search = window.location.search;
                while (match = r.exec(search.substring(1)))
                    params[d(match[1])] = d(match[2]);
                window.params = params;
            })();

            var roomid = '';
            if (localStorage.getItem(connection.socketMessageEvent)) {
                roomid = localStorage.getItem(connection.socketMessageEvent);
            } else {
                roomid = connection.token();
            }
            document.getElementById('room-id').value = roomid;
            document.getElementById('room-id').onkeyup = function() {
                localStorage.setItem(connection.socketMessageEvent, this.value);
            };

            var hashString = location.hash.replace('#', '');
            if(hashString.length && hashString.indexOf('comment-') == 0) {
              hashString = '';
            }

            var roomid = params.roomid;
            if(!roomid && hashString.length) {
                roomid = hashString;
            }

            if(roomid && roomid.length) {
                document.getElementById('room-id').value = roomid;
                localStorage.setItem(connection.socketMessageEvent, roomid);

                // auto-join-room
                (function reCheckRoomPresence() {
                    connection.checkPresence(roomid, function(isRoomExists) {
                        if(isRoomExists) {
                            connection.join(roomid);
                            return;
                        }

                        setTimeout(reCheckRoomPresence, 5000);
                    });
                })();

                disableInputButtons();
            }
        </script>

        <section class="experiment own-widgets latest-commits">
            <h2 class="header" id="updates" style="color: red;padding-bottom: .1em;"><a href="https://github.com/muaz-khan/RTCMultiConnection/commits/master">Latest Updates</a></h2>
            <div id="github-commits"></div>
        </section>

        <section class="experiment own-widgets">
            <h2 class="header" id="updates" style="color: red;padding-bottom: .1em;"><a href="https://github.com/muaz-khan/RTCMultiConnection/issues">Latest Issues</a></h2>
            <div id="github-issues"></div>
        </section>

        <section class="experiment">
            <h2 class="header" id="feedback">Feedback</h2>
            <div>
                <textarea id="message" style="height: 8em; margin: .2em; width: 98%; border: 1px solid rgb(189, 189, 189); outline: none; resize: vertical;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
            </div>
            <button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left:1em;">Enter your email too; if you want "direct" reply!</small>
        </section>

        <a href="https://github.com/muaz-khan/RTCMultiConnection" class="fork-left"></a>

        <script>
            window.useThisGithubPath = 'muaz-khan/RTCMultiConnection';
        </script>
        <script src="https://cdn.webrtc-experiment.com/commits.js" async></script>

    </article>

    <footer>
        <p>
            <a href="https://www.webrtc-experiment.com">WebRTC Experiments</a> © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
            <a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
            <a href="https://github.com/muaz-khan" target="_blank">Github</a>
        </p>
    </footer>

</body>

</html>
